package com.hemh.service;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.hemh.config.DownLoadConfig;
import com.hemh.dao.OmsBookMapper;
import com.hemh.dao.OmsBorrowMapper;
import com.hemh.dto.OmsBookDto;
import com.hemh.entity.OmsBook;
import com.hemh.entity.OmsBookExample;
import com.hemh.entity.OmsBorrow;
import com.hemh.entity.OmsBorrowExample;
import com.hemh.utils.ExcelUtils;
import com.hemh.utils.ExportUtils;
import com.hemh.utils.SendMessageUtils;
import com.hemh.utils.TimeUtils;

@Service
public class BookService {
	private final Log logger = LogFactory.getLog(BookService.class);

	@Resource
	private OmsBookMapper omsBookMapper;

	@Resource
	private OmsBorrowMapper omsBorrowMapper;

	@Resource
	private DownLoadConfig downLoadConfig;

	@Resource
	private ExcelUtils excelUtils;

	@Resource
	private SendMessageUtils sendMessageUtils;
	
	/**
	 * @author HeMingHui
	 * @since 2020-10-24
	 * @param bookId
	 * @return OmsBook
	 * @description 根据图书id查询图书信息
	 */
	public OmsBook getBookInfoById(Integer bookId) {
		OmsBook book = omsBookMapper.selectByPrimaryKey(bookId);
		return book;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-24
	 * @param book
	 * @return int
	 * @description 新增图书信息
	 */
	public int insertBook(JSONObject jsonParam) {
		int insertResult = 0;
		OmsBook book = new OmsBook();
		/** 解析封装 */
		book.setBookName(jsonParam.getString("bookName"));
		book.setBookAuthorName(jsonParam.getString("bookAuthor"));
		book.setBookTranslator(jsonParam.getString("bookTranslator"));
		book.setBookPress(jsonParam.getString("bookPress"));
		book.setBookPublic(jsonParam.getString("bookPublic"));
		book.setBookPage(jsonParam.getInteger("bookPage"));
		book.setBookType(jsonParam.getString("bookType"));
		book.setBookVersion(jsonParam.getString("bookVersion"));
		book.setBookIsbn(jsonParam.getString("bookIsbn"));
		book.setBookPrice(jsonParam.getFloat("bookPrice"));
		/** 新增图书默认库存并且不删除 */
		book.setIsStore("1");
		book.setIsDeleted("0");
		insertResult = omsBookMapper.insert(book);
		return insertResult;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-25
	 * @param bookId
	 * @param isStore
	 * @return int
	 * @description 根据图书id更新图书的库存状态
	 */
	public int updateBookStoreById(Integer bookId, String isStore) {
		int result = 0;
		OmsBook book = this.getBookInfoById(bookId);
		if (book != null) {
			book.setIsStore(isStore);
			result = omsBookMapper.updateByPrimaryKey(book);
			return result;
		}
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-25
	 * @param bookId
	 * @param isStore
	 * @return int
	 * @description 根据图书id更新图书的是否删除状态
	 */
	public int updateBookDestroyById(Integer bookId, String isDeleted) {
		int result = 0;
		OmsBook book = this.getBookInfoById(bookId);
		if (book != null) {
			book.setIsDeleted(isDeleted);
			result = omsBookMapper.updateByPrimaryKey(book);
			return result;
		}
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-25
	 * @param bookId
	 * @return List<OmsBook>
	 * @description 查询未删除的图书信息(分页查询)
	 */
	public List<OmsBook> getBookInfoNoDeleted(Integer page, Integer pageSize) {
		List<OmsBook> bookList = new ArrayList<OmsBook>();
		OmsBookExample example = new OmsBookExample();
		example.createCriteria().andIsDeletedEqualTo("0");
		PageHelper.startPage(page, pageSize);
		bookList = omsBookMapper.selectByExample(example);
		return bookList;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-25
	 * @param bookId
	 * @return List<OmsBook>
	 * @description 根据图书名称模糊查询图书信息(分页查询)
	 */
	public List<OmsBook> getBookInfoByName(String bookName, Integer page, Integer pageSize) {
		List<OmsBook> bookList = new ArrayList<OmsBook>();
		OmsBookExample example = new OmsBookExample();
		/** 不区分大小写 */
		example.or().andBookNameLike("%" + bookName.trim().toUpperCase() + "%");
		example.or().andBookNameLike("%" + bookName.trim().toLowerCase() + "%");
		PageHelper.startPage(page, pageSize);
		bookList = omsBookMapper.selectByExample(example);
		return bookList;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-26
	 * @param book
	 * @return int
	 * @description 通过主键id更新图书信息
	 */
	public int updateBookInfoById(JSONObject jsonParam) {
		int result = 0;/** 0-代表更新不成功共, 1-代表更新成功 */
		Integer bookId = jsonParam.getInteger("bookId");
		OmsBook book = omsBookMapper.selectByPrimaryKey(bookId);
		if (book == null) {/** 更新不存在的实体, 返回0 */
			return result;
		}
		/** 解析json, 封装对象 */
		book.setBookName(jsonParam.getString("bookName"));
		book.setBookAuthorName(jsonParam.getString("bookAuthorName"));
		book.setBookTranslator(jsonParam.getString("bookTranslator"));
		book.setBookPress(jsonParam.getString("bookPress"));
		book.setBookPublic(jsonParam.getString("bookPublic"));
		book.setBookPage(jsonParam.getInteger("bookPage"));
		book.setBookType(jsonParam.getString("bookType"));
		book.setBookVersion(jsonParam.getString("bookVersion"));
		book.setBookIsbn(jsonParam.getString("bookIsbn"));
		book.setBookPrice(jsonParam.getFloat("bookPrice"));
		/** 更新图书信息 */
		result = omsBookMapper.updateByPrimaryKey(book);
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-26
	 * @return List<OmsBook>
	 * @description 查询的书籍列表(deleted=0), 用于导出至excel
	 */
	public List<OmsBook> getBookListAll() {
		List<OmsBook> bookList = new ArrayList<OmsBook>();
		OmsBookExample example = new OmsBookExample();
		example.or().andIsDeletedEqualTo("0");
		bookList = omsBookMapper.selectByExample(example);
		return bookList;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-26
	 * @return void
	 * @description 导出模板
	 */
	@SuppressWarnings("resource")
	public void exportBookTemplate(HttpServletRequest request, HttpServletResponse response) {
		String templatePath = downLoadConfig.getTemplatePath() + "bookTemplate.xls";
		String fileName = "BookTemplate.xls";
		try {
			fileName = new String(fileName.getBytes(), "utf-8");
			response.setCharacterEncoding("utf-8");
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.setContentType("application/x-download");
			byte[] buff = new byte[1024];
			BufferedInputStream bis = null;
			OutputStream os = null;
			os = response.getOutputStream();
			/** 创建输入流 */
			bis = new BufferedInputStream(new FileInputStream(templatePath));
			int i = 0;
			/** 读取输入流的数据到buff中 */
			while ((i = bis.read(buff)) != -1) {
				/** 把buff中的数据全部写入输出流 */
				os.write(buff, 0, i);
			}
			/** 把内存中的数据写入输出流 */
			os.flush();
		} catch (Exception e) {
			logger.error("导出excel模板出现异常:", e);
		}

	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-26
	 * @return void
	 * @description 图书信息导出至excel
	 */
	public void exportBookInfo(HttpServletRequest request, HttpServletResponse response) {
		/** 图书信息导出逻辑, 导出delete=0的书籍信息 */
		List<OmsBook> bookList = this.getBookListAll();
		String templatePath = downLoadConfig.getTemplatePath() + "bookTemplate.xls";
		String fileName = "Books.xls";
		try {
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			HSSFWorkbook wb = ExportUtils.exportBookList(templatePath, bookList);
			wb.write(os);
			byte[] content = os.toByteArray();
			InputStream is = new ByteArrayInputStream(content);
			ServletOutputStream sout = response.getOutputStream();
			BufferedInputStream bis = null;
			BufferedOutputStream bos = null;
			fileName = new String(fileName.getBytes(), "utf-8");
			response.setCharacterEncoding("utf-8");
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.setContentType("application/x-download");
			try {
				bis = new BufferedInputStream(is);
				bos = new BufferedOutputStream(sout);
				byte[] buff = new byte[2048];
				int bytesRead;
				/** 文件读写循环 */
				while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
					bos.write(buff, 0, bytesRead);
				}
			} catch (Exception e) {
				logger.error("导出excel出现异常:", e);
			} finally {
				if (bis != null)
					bis.close();
				if (bos != null)
					bos.close();
			}
		} catch (Exception e) {
			logger.error("导出excel出现异常:", e);
		}
	}

	/**
	 * @author HeMingHui
	 * @since 2020-10-26
	 * @return int
	 * @description insert图书Dto对象
	 */
	public int insertBooKDto(OmsBookDto bookDto) {
		int result = 0;
		OmsBook record = new OmsBook();
		/** dto封装entity对象 */
		record.setBookName(bookDto.getBookName());
		record.setBookAuthorName(bookDto.getBookAuthorName());
		record.setBookPress(bookDto.getBookPress());
		record.setBookPrice(bookDto.getBookPrice());
		/** 导入默认 isStore=1, isDeleted=0 */
		record.setIsStore("1");
		record.setIsDeleted("0");
		/** insert entity to Database */
		result = omsBookMapper.insert(record);
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-11-01
	 * @return void
	 * @description 导入图书信息excel至数据库
	 */
	public void importBookInfo(MultipartFile file) {
		List<OmsBookDto> bookDtoList = new ArrayList<OmsBookDto>();
		try {
			bookDtoList = excelUtils.readExcelFileToDTO(file, OmsBookDto.class);
			bookDtoList.stream().forEach(item -> {
				this.insertBooKDto(item);
			});
		} catch (IOException e) {
			logger.error("导入excel出现异常:", e);
		}
	}

	/**
	 * @author HeMingHui
	 * @since 2020-11-02
	 * @return int
	 * @description 借阅图书
	 */
	public int bookBrrow(JSONObject jsonParam) {
		int result = 0;
		OmsBorrow omsBorrow = new OmsBorrow();
		/** 解析封装 */
		omsBorrow.setBookBorrower(jsonParam.getString("bookBorrower"));
		omsBorrow.setBorrowBookId(jsonParam.getInteger("borrowBookId"));
		omsBorrow.setDailyPrice(jsonParam.getFloat("dailyPrice"));
		omsBorrow.setBorrowPrice(jsonParam.getFloat("borrowPrice"));
		LocalDateTime expectReturn = TimeUtils.parseStringToDateTime(jsonParam.getString("expectReturnTime"),
				"yyyy-MM-dd HH:mm:ss");
		omsBorrow.setExpectReturnTime(expectReturn);
		/** 借阅时间默认定为当前 */
		omsBorrow.setBorrowStartTime(TimeUtils.getLocalDateTimeNow());
		/** 借阅默认, 未归还 */
		omsBorrow.setIsReturn("0");
		/** 借阅默认, 未逾期 */
		omsBorrow.setIsOverdue("0");
		/** 记录逻辑删除默认：未删除 */
		omsBorrow.setDeleted("0");
		result = omsBorrowMapper.insert(omsBorrow);
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-11-03
	 * @param isReturn
	 * @return List<OmsBorrow>
	 * @description 根据是否归还状态查询借还表记录
	 */
	public List<OmsBorrow> getBorrowListByIsReturn(String isReturn) {
		List<OmsBorrow> borrowList = new ArrayList<OmsBorrow>();
		OmsBorrowExample example = new OmsBorrowExample();
		example.or().andIsReturnEqualTo(isReturn);
		borrowList = omsBorrowMapper.selectByExample(example);
		return borrowList;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-11-03
	 * @param userNumber
	 * @param bookId
	 * @return int
	 * @description 通过usernumber+bookId更新图书的IsOverdue字段、overdueDays字段
	 */
	public int updateBorrowOverdue(String userNumber, int bookId) {
		int result = 0;
		OmsBorrowExample example = new OmsBorrowExample();
		example.createCriteria().andBookBorrowerEqualTo(userNumber).andBorrowBookIdEqualTo(bookId);
		OmsBorrow record = omsBorrowMapper.selectOneByExample(example);
		Date endDate = TimeUtils.localDateTimeConvertToDate(TimeUtils.getLocalDateTimeNow());
		Date startDate = TimeUtils.localDateTimeConvertToDate(record.getExpectReturnTime());
		long days = TimeUtils.minuxToDaysByDate(startDate, endDate);
		record.setIsOverdue("1");
		record.setOverdueDays(Integer.valueOf((String.valueOf(days))));
		result = omsBorrowMapper.updateByPrimaryKey(record);
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-11-04
	 * @param userNumber
	 * @param bookId
	 * @return int
	 * @description 根据userNumber与bookId更新还书的相关字段
	 */
	public int returnBook(String userNumber, int bookId) {
		int result = 0;
		LocalDateTime nowTime = TimeUtils.getLocalDateTimeNow();
		OmsBorrowExample example = new OmsBorrowExample();
		example.or().andBookBorrowerEqualTo(userNumber).andBorrowBookIdEqualTo(bookId);
		OmsBorrow record = omsBorrowMapper.selectOneByExample(example);
		LocalDateTime borrowTime = record.getBorrowStartTime();
		LocalDateTime expectReturnTime = record.getExpectReturnTime();
		// 当前日期
		Date nowDate = TimeUtils.localDateTimeConvertToDate(nowTime);
		// 借阅时间
		Date borrowDate = TimeUtils.localDateTimeConvertToDate(borrowTime);
		// 期望归还日期
		Date exReturnDate = TimeUtils.localDateTimeConvertToDate(expectReturnTime);
		/** 更新当前记录 */
		record.setActualReturnTime(nowTime);
		record.setIsReturn("1");
		if (exReturnDate.before(nowDate)) {// 超限了
			record.setIsOverdue("1");
		} else {
			record.setIsOverdue("0");
		}
		//超限天数
		long overDays = TimeUtils.minuxToDaysByDate(exReturnDate, nowDate);
		//实际使用天数
		long actualUseDays = TimeUtils.minuxToDaysByDate(borrowDate, nowDate);
		record.setOverdueDays(Integer.valueOf(String.valueOf(overDays)));
		/** 计算 --> 结算金额 (多退少补)*/
		float settlementPrice = 0.0f;
		settlementPrice = record.getBorrowPrice() - actualUseDays * record.getDailyPrice();
		record.setSettlementPrice(settlementPrice);
		result = omsBorrowMapper.updateByPrimaryKey(record);
		/** 结算的提醒 */
		logger.info(sendMessageUtils.sendSettlementPriceMessage(userNumber, bookId, nowTime, settlementPrice));;	
		
		new Thread(() -> {

			/** 提醒消息需要插入邮件表 */
			
			
		}).start();
		
		return result;
	}

	/**
	 * @author HeMingHui
	 * @since 2020-11-05
	 * @param id
	 * @return int 0-失败, 1-成功
	 * @description 根据主键id更新bookBorrow表的deleted字段
	 */
	public int updateBookBorrowDeletedById(int bookBorrowId, String deleted) {
		int result = 0;
		OmsBorrowExample example = new OmsBorrowExample();
		example.or().andIdEqualTo(bookBorrowId);
		OmsBorrow record = omsBorrowMapper.selectOneByExample(example);
		if(record == null) {
			return result;
		}
		record.setDeleted(deleted);
		result = omsBorrowMapper.updateByPrimaryKey(record);
		return result;
	}
}
